#include <gio/gio.h>
#include <gio/gunixinputstream.h>
#include "position.h"

#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/time.h>

char pieces[6] = {'P', 'N', 'B', 'R', 'K', 'Q' };

int char_to_piece (char a) {
	int i = 0;
	while (a != pieces [i++]);
		
	return i-1;
}

static void
parse_move (Position *pos, gchar *mstr)
{
	Move m;
	gint len;
	gchar *str = g_strdup (mstr);
	
	/* initialize move with null values */
	m.from_file = -1;
	m.to_file = -1;
	m.from_rank = -1;
	m.to_rank = -1;
	m.captured_piece = -1;
	m.piece = -1;
	m.promote_to = -1;
	m.type = M_REGULAR;
	
	len = strlen (str);
	/* remove +/# from the end if exists*/
	if (str[len-1] == '+' || str[len-1]  == '#')
		str[--len] = '\0';
	
	switch (len) {
	case 2: // e4
		m.to_file = m.from_file = str[0] - 'a'; ;
		m.to_rank = str[1] - '1';
		m.piece = PAWN;
		break;
	case 3: // Nf6 0-0
		if (str[0] == 'O' && str[2] == 'O') {
			m.type = M_KCASTLE;	
		} else {
			m.to_file = str[1] - 'a';
			m.to_rank = str[2] - '1';
			m.piece = char_to_piece (str[0]);
		}	
		break;
	case 4: 
		if (str[2] == '=') {//f1=N
			m.type = M_PROMOTE;
			m.piece = PAWN;
			m.promote_to = char_to_piece (str[3]);
			m.from_file = m.to_file = str[0] - 'a';
			m.to_rank = str[1] - '1';
		} else if (str[1] == '@') {	// p@c3
			m.piece = char_to_piece (str[0]);
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			m.type = M_DROP;
		} else if (str[1] == 'x' && isupper (str[0])) {	// Bxc3
			m.type = M_CAPTURE;
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			m.piece = char_to_piece (str[0]);
		} else if (str[1] == 'x' && islower (str[0])) {	// dxc3
			m.type = M_CAPTURE;
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			m.from_file = str[0] - 'a';
			m.piece = PAWN;
		} else if (isdigit (str[1])) {	// N7e4
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			m.from_rank = str[1] - '1';
			m.piece = char_to_piece (str[0]);
		} else if (isalpha (str[1])) {	// Nfe4 
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			m.from_file = str[1] - 'a';
			m.piece = char_to_piece (str[0]);
		}
		break;
	case 5:
		if (str[0] == 'O' && str[2] == 'O' && str[4] == 'O') { // 0-0-0
			m.type = M_QCASTLE;	
		} else if (str[2] == 'x' && isalpha (str[1])) { // Nfxe5
			m.piece = char_to_piece (str[0]);
			m.type = M_CAPTURE;
			m.to_file = str[3] - 'a';
			m.to_rank = str[4] - '1';
			m.from_file = str[1] - 'a';
		} else if (str[2] == 'x' && isdigit (str[1])) {	// N7xe5
			m.type = M_CAPTURE;
			m.to_file = str[3] - 'a';
			m.to_rank = str[4] - '1';
			m.from_rank = str[1] - '1';
			m.piece = char_to_piece (str[0]);
		} else { //Nf4e4
			m.piece = char_to_piece (str[0]);
			m.to_file = str[3] - 'a';
			m.to_rank = str[4] - '1';
			m.from_rank = str[2] - '1';
			m.from_file = str[1] - 'a';
		}
		
		break;
	case 6://fxc1=N
		if (str[4] == '=') {
			m.type = M_PROMOTE; //wtf ? promote + capture?
			m.piece = PAWN;
			m.promote_to = char_to_piece (str[5]);
			m.from_file = str[0] - 'a';
			m.to_file = str[2] - 'a';
			m.to_rank = str[3] - '1';
			
		} else { //Nf4xe4.  its possible with four knights
			m.type = M_CAPTURE;
			m.piece = char_to_piece (str[0]);
			m.to_file = str[4] - 'a';
			m.to_rank = str[5] - '1';
			m.from_rank = str[2] - '1';
			m.from_file = str[1] - 'a';
		}
		break;
	default:
		g_print ("blah blah str = %s\n", str);
		return;
	}
	
	position_do_move (pos, &m);
	position_print_fen (pos);
	//position_print (pos);
	g_free (str);
	
}



gint
main (gint argc, gchar *argv[])
{
	Position *pos1, *pos2;

	g_type_init ();
	pos1 = position_new ();
	pos2 = position_new ();
	
	GInputStream *moves_input = g_unix_input_stream_new (1, TRUE);
	GString *move_string = g_string_new ("");
	gchar buf[1];
	while (TRUE) {
		g_input_stream_read (moves_input, buf, 1, NULL, NULL);
		
		if (buf[0] == '\n') {
			parse_move (pos1, move_string->str);
			g_string_erase (move_string, 0, move_string->len);
		} else {
			move_string = g_string_append_c (move_string, buf[0]);
		}
	}
	
	
 	return 0;
}
